﻿#if !Profile && TRUNKTQ
using System;
using System.Diagnostics;
using O1.Kernel.Storage;
using O1.Kernel.Storage.Transactions;

namespace O1.Profiling
{
    class Program
    {
        private const int size = 1024 * 1024;

        static void Main(string[] args)
        {
            var bytesAllocated = GC.GetTotalMemory(true);
            var stopwatch = Stopwatch.StartNew();

            var trunk = new MemoryTrunk(size, 0);

            stopwatch.Stop();
            Console.WriteLine("");
            var difference = GC.GetTotalMemory(true) - bytesAllocated;
            Console.WriteLine("Allocated " + size + " trunk storage.");
            Console.WriteLine("...in " + stopwatch.ElapsedMilliseconds + " milliseconds.");

            stopwatch.Restart();
            using (var token = new ConcurrentScope())
            {
                for (int i = 0; i < size; i++)
                {

                    trunk.AllocateVertex((i % 2 == 0) ? new byte[1096] : new byte[256], token);
                }

                trunk.TryCommit(token);
            }

            using (var token = new ConcurrentScope())
            {
                for (int i = 1; i < size + 1; i++)
                {
                    var newVersion = trunk.ReadVertex(i, token);
                    trunk.WriteVertex(i, newVersion, token);
                }

                trunk.TryCommit(token);
            }

            // Quirk, 1 based indexing and 0 is empty. This is OK, possibly desirable. It allows 0 to 
            // mean 'uninitialized' when referring to a cell address.
            ////for (int i = 1; i < size + 1; i++)
            ////{
            ////    using (var token = new ConcurrentScope())
            ////    {
            ////        var newVersion = trunk.ReadVertex(i, token);
            ////        trunk.WriteVertex(i, newVersion, token);
            ////        trunk.TryCommit(token);
            ////    }
            ////}

            stopwatch.Stop();
            Console.WriteLine("Processed " + size + " cells in " + stopwatch.ElapsedMilliseconds + " milliseconds.");
            Console.WriteLine("... " + stopwatch.ElapsedMilliseconds / size + " milliseconds per cell.");
            Console.ReadLine();
        }
    }

    internal class MemTrunkStub
    {
        public MemTrunkStub(int i1, int i2)
        {

        }

        internal void AllocateVertex(byte[] newCell, ConcurrentScope token)
        {
        }

        internal void TryCommit(ConcurrentScope token)
        {
        }

        internal long ReadVertex(int i, ConcurrentScope token)
        {
            return 0;
        }

        internal void WriteVertex(int i, long newVersion, ConcurrentScope token)
        {
        }
    }
}

#endif